import { ChangeDetectorRef, Component, ElementRef, OnInit, SimpleChanges, ViewChild } from '@angular/core';
import { CheckableRelation, DataTableComponent, EditableTip, TableCheckOptions, TableWidthConfig } from 'ng-devui/data-table';
import { BroadcastService } from 'src/app/services/broadcast.service';
// import { CommonDataService } from 'src/app/services/common-data.service';
import { MateDataService } from 'src/app/services/mate_data.service';
// import { createOfflineCompileUrlResolver } from '@angular/compiler';
import { LoadingType } from 'ng-devui/loading';
import { DialogService } from 'ng-devui/modal';
import { CommonDataService } from 'src/app/services/common-data.service';
import { SessionService } from 'src/app/services/session.service';
import { ActivatedRoute, Router } from '@angular/router';

@Component({
    selector: 'app-excel-table',
    templateUrl: './excel-table.component.html',
    styleUrls: ['./excel-table.component.scss']
})
export class ExcelTableComponent implements OnInit {

    @ViewChild(DataTableComponent, { static: false }) datatable: any;
    @ViewChild('dataTable', { static: false }) sheetTable: any;

    editableTip = EditableTip.btn;
    private _handler: any = [];
    constructor(
        private broadcastService: BroadcastService,
        private mateDataService: MateDataService,
        private dialogService: DialogService,
        private ref: ElementRef,
        private commonDataSrv: CommonDataService,
        private sessionSvc: SessionService,
        private router: Router,
        private fileRouter: ActivatedRoute,
    ) {
        this.loading = undefined;

        this._handler.push(
            this.broadcastService.on('abc').subscribe((res) => {
            })
        );

        this._handler.push(
            this.broadcastService.on('refreshTableData_import').subscribe((res) => {
                if (res) {
                    this.msgs = [
                        { severity: 'success', summary: '成功', content: '导入数据成功！' },
                    ]
                }
                this.totalSource = res;
                this.refreshDataBySource(this.totalSource, true);
                this.saveLabel = '上传保存';
                this.isSaved = false;
                this.isImport = true;
                // this.isAvaliable = false;
                this.saveTimeStr = '';
            })
        );
    }

    exportData: any[] = [];
    basicDataSource: any = [];
    titleSource: any = [];
    totalSource: any;
    saveBaseData: any;
    editedBaseData: any = new Map();
    addedBaseData: any = [];
    objId: any;
    personalInfomation: any;
    searchText: any;
    msgs: Array<Object> = [];
    tableWidthConfig: TableWidthConfig[] = [];
    loading: LoadingType;
    saveTimeStr: string = '';
    saveLabel: string = '上传保存';
    isImport: boolean = false;
    isSaved: boolean = false;
    isAvaliable: boolean = false;

    curEditItem: any;

    ngAfterViewInit() {

    }

    ngOnChanges(changes: SimpleChanges): void {
        //Called before any other lifecycle hook. Use it to inject dependencies, but avoid any serious work here.
        //Add '${implements OnChanges}' to the class.

    }

    ngOnInit() {
        this.fileRouter.queryParams.subscribe((res: any) => {
            if (!this.isEmptyObject(res)) {
                this.objId = res.objId;
                this.refreshDataBySource(this.objId)
                this.isSaved = true;
                this.isImport = true;
            } else {
                this.basicDataSource = [];
                this.titleSource = [];
                this.totalSource = [];
                this.saveBaseData = [];
                this.objId = '';
                this.saveTimeStr = '';
                this.saveLabel = '上传保存';
                this.isSaved = false;
                // this.isAvaliable = false;
            }
        })

    }

    // 模糊搜索
    onSearch(term: string) {
        if (this.basicDataSource.length === 0 && !this.isAvaliable) {
            this.msgs = [
                { severity: 'warn', content: '当前没有数据,请先导入数据!' },
            ];
            return;
        }

        if (!term) {
            this.basicDataSource = [];
            this.basicDataSource = this.saveBaseData;
            this.isAvaliable = false;
        } else {
            this.basicDataSource = this.filterOne(this.basicDataSource, term, this.titleSource)
            this.isAvaliable = true;
        }
    }

    // 模糊搜索过滤出结果
    filterOne(datalist, value: string, type) {
        let s = datalist.filter((item) => {
            for (let j = 0; j < type.length; j++) {
                let currentValue = item[type[j].label] ? item[type[j].label] : '';
                if (currentValue.value.toString().indexOf(value) >= 0) {
                    return item;
                }
            }
        });
        // return s.length > 0 ? s : [];
        return s;
    }


    // 保存数据
    saveData(isDis) {
        if (isDis) return;

        // 判断当前表格是否有数据
        if (this.totalSource.length <= 0) {
            this.msgs = [
                {
                    severity: 'error',
                    summary: '失败',
                    content: '当前表格没有数据！'
                },
            ];
            return;
        }

        // 判断是否保存过，未保存过走插入数据，保存过走更新数据
        if (!this.isSaved) {
            this.basicDataSource = this.baseDataSourceExtraction(this.basicDataSource, this.titleSource);
            const postBody = this.totalSource;
            postBody.fieldList.push({
                fieldNum: 0,
                label: 'row',
                fieldId: ''
            });
            this.loading = this.mateDataService.postExcelAllData(postBody).subscribe((res: any) => {
                if (res.status === 'SUCCESS') {
                    const { userId } = this.sessionSvc.getSessionValue('user');
                    this.msgs = [
                        {
                            severity: 'success',
                            summary: '成功',
                            content: '保存数据成功！' + '共保存了' + res.result.modifiedRows +
                                '行和' + res.result.modifiedColumns + '列.'
                        },
                    ]
                    this.totalSource = res.result;
                    // this.basicDataSource =this.baseDataSourceRestore(this.basicDataSource,this.titleSource);
                    this.refreshDataBySource(this.totalSource, true);
                    this.saveLabel = '保存';
                    this.isSaved = true;
                    this.isImport = true;
                    // this.isAvaliable = true;
                    const { objId, orgId, label } = res.result;
                    const newFileNode = {
                        objId,
                        orgId,
                        label
                    };
                    this.broadcastService.broadcast('refreshTree', { userId: userId, newFileNode });
                    this.saveTimeStr = '最新保存时间：' + new Date().toLocaleString();
                } else if (status.toUpperCase() === 'TOKEN_FAILURE') {
                    this.msgs = [
                        { severity: 'error', summary: '错误', content: '登录信息失效！请重新登录！' },
                    ];
                    this.router.navigate(['login'])
                } else {
                    this.msgs = [
                        { severity: 'error', summary: '失败', content: '保存数据失败！' },
                    ]
                }
            });
        } else {
            if (this.editedBaseData.size > 0) {
                let updateData: any = [];
                for (let value of this.editedBaseData.values()) {
                    updateData.push(value)
                }
                updateData = this.baseDataSourceExtraction(updateData, this.titleSource);
                this.loading = this.mateDataService.updateSheetData(updateData).subscribe((res: any) => {
                    if (res.status === "SUCCESS") {
                        this.msgs = [
                            {
                                severity: 'success',
                                summary: '成功',
                                content: '修改保存成功！' + '保存了' + res.result.length +
                                    '行。'
                            },
                        ];
                        this.refreshDataBySource(this.objId);
                        this.editedBaseData.clear();
                        this.saveLabel = '保存';
                        // this.isSaved = true;
                        this.isAvaliable = false;
                        this.saveTimeStr = '最新保存时间：' + new Date().toLocaleString();
                    } else if (status.toUpperCase() === 'TOKEN_FAILURE') {
                        this.msgs = [
                            { severity: 'error', summary: '错误', content: '登录信息失效！请重新登录！' },
                        ];
                        this.router.navigate(['login'])
                    } else {
                        this.msgs = [
                            { severity: 'error', summary: '失败', content: '保存数据失败！' },
                        ]
                    }
                });
                // this.saveTimeStr = '最新保存时间：' + new Date().toLocaleString();
            } else {
                this.msgs = [
                    { severity: 'error', summary: '失败', content: '没有修改数据！' },
                ];
                return;
            }
        }
    }

    addNewRow(isDis) {
        // this.addedBaseData = [];
        const { userName, userId } = this.sessionSvc.getSessionValue('user');
        if (isDis) return;
        let rowItem = this.basicDataSource.length > 0 ? this.basicDataSource.slice(-1) : [{ row: -1 }];
        let info: any = {};
        let key = '';
        for (let j = 0; j < this.titleSource.length; j++) {
            key = this.titleSource[j].label;
            info[key] = '';
        }
        info["row"] = parseInt(rowItem[0].row) + 1;
        info['objId'] = this.objId;
        info['orgId'] = userId;
        info['ownerId'] = userId;
        info['lastModifiedBy'] = userName;
        info['createBy'] = userName;


        this.mateDataService.addNewRow([info]).subscribe((res: any) => {
            let backResult = this.baseDataSourceRestore(res.result, this.titleSource, true)[0];

            this.basicDataSource = [...this.basicDataSource, backResult];
            this.saveBaseData = JSON.parse(JSON.stringify(this.basicDataSource));;

            this.editedBaseData.set(backResult.dataId, backResult);

            setTimeout(() => {
                let now = this.ref.nativeElement.querySelector('.devui-scrollbar');
                now.scrollTop = now.scrollHeight;
            });
        })

    }

    // 打开删除提醒框
    openDeleteDialog(isDis) {
        if (isDis) return;
        const results = this.dialogService.open({
            id: 'dialog-service',
            width: '400px',
            maxHeight: '600px',
            title: '',
            html: true,
            content: '确认删除所选数据？',
            backdropCloseable: true,
            dialogtype: 'warning',
            buttons: [
                {
                    cssClass: 'primary',
                    text: 'Ok',
                    handler: ($event: Event) => {
                        this.deleteRows();
                        results.modalInstance.hide();
                    },
                },
                {
                    id: 'btn-cancel',
                    cssClass: 'common',
                    text: 'Cancel',
                    handler: ($event: Event) => {
                        results.modalInstance.hide();
                    },
                },
            ],
        });
    }

    // 删除所选行数据
    deleteRows() {
        const deleteRows = this.datatable.getCheckedRows();
        this.mateDataService.deleteSheetRows(deleteRows).subscribe((res: any) => {
            if (res.status === "SUCCESS") {
                this.msgs = [
                    {
                        severity: 'success',
                        summary: '成功',
                        content: '删除数据成功！'
                    },
                ];
                this.refreshDataBySource(this.objId);
            } else if (status.toUpperCase() === 'TOKEN_FAILURE') {
                this.msgs = [
                    { severity: 'error', summary: '错误', content: '登录信息失效！请重新登录！' },
                ];
                this.router.navigate(['login'])
            } else {
                this.msgs = [
                    {
                        severity: 'error',
                        summary: '失败',
                        content: '删除数据失败！'
                    },
                ];
            }
        });
    }


    // 刷新表格数据
    async refreshDataBySource(dataSource, isimport?) {

        if (isimport) {
            const totalSource = dataSource;
            this.refreshData(totalSource);
        } else {
            this.mateDataService.getSheetData(dataSource).subscribe((res: any) => {
                if (res.status === "SUCCESS") {
                    this.totalSource = res.result;
                    // this.basicDataSource
                    this.refreshData(this.totalSource);
                } else if (status.toUpperCase() === 'TOKEN_FAILURE') {
                    this.msgs = [
                        { severity: 'error', summary: '错误', content: '登录信息失效！请重新登录！' },
                    ];
                    this.router.navigate(['login'])
                }
            })
        }
    }

    refreshData(totalSource) {

        // this.fileInfo.name = totalSource.name;
        this.objId = totalSource.objId;

        this.titleSource = totalSource.fieldList.sort(this.compare('fieldNum')).filter(e => e.label !== 'row');

        this.basicDataSource = totalSource.dataList.sort(this.compare('row'));
        this.basicDataSource = this.baseDataSourceRestore(this.basicDataSource, this.titleSource);
        this.saveBaseData = JSON.parse(JSON.stringify(this.basicDataSource));

        this.tableWidthConfig = [
            { field: 'checkbox', width: '36px' },
            { field: '$index', width: '100px' }];
        for (let i = 0; i < this.titleSource.length; i++) {
            this.tableWidthConfig.push({
                field: this.titleSource[i].label,
                width: '100px',
            });
        }
    }


    compare(property) {
        return function (a, b) {
            var value1 = a[property];
            var value2 = b[property];
            return value1 - value2;
        }
    }

    // 将不用传给后端的数据字段剔除
    baseDataSourceExtraction(baseData, titleData) {
        baseData.forEach((item) => {
            // 只传value的值
            for (let i = 0; i < titleData.length; i++) {
                let key = titleData[i].label;
                const { value } = item[key]
                if (value || value === "") {
                    item[key] = value;
                }
            }
        });
        return baseData;
    }

    // 将不用传给后端的数据字段加回来并初始化
    baseDataSourceRestore(baseData, titleData, isAddRow?) {
        // 将需要的editing_...和Edited标识字段加上
        baseData.forEach((item) => {
            for (let i = 0; i < titleData.length; i++) {
                let key = titleData[i].label;

                let temp = item[key];
                item[key] = {};
                item[key]['value'] = temp;
                item[key]['isEditing_' + key] = false;
                if (isAddRow) {
                    item[key]['edited'] = true;
                } else {
                    item[key]['edited'] = false;
                }
            }
        });
        return baseData;
    }

    // 表格头拉升宽度
    onResize({ width }, field) {
        const index = this.tableWidthConfig.findIndex((config) => {
            return config.field === field;
        });
        if (index > -1) {
            this.tableWidthConfig[index].width = width + 'px';
        }
    }

    // 编辑表格数据前
    beforeEditStart = (rowItem, field) => {
        return true;
    }

    // 编辑表格结束前
    beforeEditEnd = (rowItem, field) => {

        let savedRowItem = this.saveBaseData.find(e => e.row === rowItem.row)

        // 将修改的部分存起来
        if (this.isSaved && savedRowItem[field].value !== rowItem[field].value) {
            this.editedBaseData.set(rowItem.dataId, rowItem);
            rowItem[field].edited = true;
        }

        if (savedRowItem[field].value === rowItem[field].value) {
            rowItem[field].edited = false;
        }

        return true;
    }

    // 选择复选框时设置选中状态
    onRowCheckChange(checked, rowIndex, nestedIndex, rowItem) {
        rowItem.$checked = checked;
        rowItem.$halfChecked = false;
        this.datatable.setRowCheckStatus({
            rowIndex: rowIndex,
            nestedIndex: nestedIndex,
            rowItem: rowItem,
            checked: checked
        });
    }

    isEmptyObject(info) {
        for (let key in info)  
            return false;  
        return true;  
    }  
}

